package com.homelink.crashhandle.util;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Environment;
import android.util.Log;
import com.callrecorder.android.Constants;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by Fcy on 2016/1/7.
 */
public class FileUtils
{
	public static boolean isFileExist(File file)
	{
		if (file == null)
			return false;
		return file.exists();
	}

	/**
	 * @param context
	 * @param isCrash
	 * @return
	 */
	public static String getLogZipName(Context context, boolean isCrash)
	{
		SharedPreferences sp = context.getSharedPreferences(
		        ConstantsUtils.HOMELINK_LOG, Context.MODE_PRIVATE);
		String ucId = sp.getString(ConstantsUtils.UC_ID, null);
		return getLogZipName(context, ucId, isCrash);
	}

	/**
	 * 获取log压缩后的文件名
	 * 
	 * @param context
	 * @param account
	 *            账号
	 * @param isCrash
	 *            是否是crash
	 * @return
	 */
	public static String getLogZipName(Context context, String account,
	        boolean isCrash)
	{
		int is_crash = isCrash ? ConstantsUtils.LogType.is_crash
		        : ConstantsUtils.LogType.no_crash;
		String packageName = isCrash ? context.getPackageName()
		        : ConstantsUtils.HOMELINK_PACKAGENAME;
		return packageName + "_" + ConstantsUtils.ANDROID + "_" + account + "_"
		        + System.currentTimeMillis() + "_" + is_crash + "_"
		        + DeviceUtils.getUUID(context) + ConstantsUtils.FILE_TYPE;
	}

	/**
	 * 如果不存在则创建（文件或者文件夹）
	 *
	 * @param file
	 * @param isFile
	 *            是file还是dir
	 * @return file
	 */
	public static File existOrCreate(File file, boolean isFile)
	{
		if (file == null)
			return null;

		boolean isCreate = false;

		if (file.exists())
		{
			isCreate = true;
		}
		else
		{
			if (isFile)
			{
				try
				{
					// 有可能创建失败 boolean
					isCreate = file.createNewFile();
				} catch (IOException e)
				{
					e.printStackTrace();
					isCreate = false;
				}
			}
			else
			{
				isCreate = file.mkdirs();
			}
		}

		return isCreate ? file : null;
	}

	// /**
	// * /mnt/sdcard/android/data/com.xxx.xxx/files/dir
	// *
	// * @param context
	// * @param dir 文件夹名
	// * @return 外部File路径，如果sd卡不存在，返回null，如果dir=null，返回files目录
	// */
	// public static File getDiskFilesDir(Context context, String dir) {
	// File file;
	// if (!Environment.MEDIA_MOUNTED
	// .equals(Environment.getExternalStorageState())) {
	// return null;
	// }
	//
	// file = context.getExternalFilesDir(null);
	// if (dir == null) {
	// return file;
	// }
	//
	// File fileDir = new File(file, dir);
	// if (!fileDir.exists()) {
	// fileDir.mkdir();
	// }
	// return fileDir;
	// }

	/**
	 * 获取sd卡根目录
	 *
	 * @return null if not exist
	 */
	public static File getSdRoot()
	{
		if (!Environment.MEDIA_MOUNTED
		        .equals(Environment.getExternalStorageState()))
			return null;
		return Environment.getExternalStorageDirectory();
	}

	public static String getSdRootPath()
	{
		return getSdRoot() == null ? null : getSdRoot().getAbsolutePath();
	}

	/**
	 * 存放所有log的根目录 sd/homelink_logs/log_files/
	 * 
	 * @return
	 */
	public static File getLogFilesDir()
	{
		if (getSdRoot() == null)
			return null;
		String path = getSdRootPath() + File.separator
		        + ConstantsUtils.LOG_DIR_ROOT_NAME + File.separator
		        + ConstantsUtils.LOG_FILES_DIR_NAME;
		return existOrCreate(new File(path), false);
	}

	/**
	 * 获取 对应包名的 log存放目录 sd/homelink_logs/log_files/org.jaaksi.test/log文件
	 *
	 * @param context
	 * @return
	 */
	public static File getPackageLogDir(Context context)
	{
		if (getSdRoot() == null)
			return null;
		String path = getSdRootPath() + File.separator
		        + ConstantsUtils.LOG_DIR_ROOT_NAME + File.separator
		        + ConstantsUtils.LOG_FILES_DIR_NAME + File.separator
		        + context.getPackageName();
		return existOrCreate(new File(path), false);

	}

	/**
	 * log push目录， sd/homelink_logs/log_push
	 *
	 * @return
	 */
	public static File getPushDir()
	{
		if (getSdRoot() == null)
			return null;
		String path = getSdRootPath() + File.separator
		        + ConstantsUtils.LOG_DIR_ROOT_NAME + File.separator
		        + ConstantsUtils.LOG_PUSH_DIR_NAME;

		return existOrCreate(new File(path), false);
	}

	/**
	 * 获取log push目录， sd/homelink_logs/log_push下的所有文件
	 * 
	 * @return
	 */
	public static List<File> getPushFiles()
	{
		List<File> list = new ArrayList<>();
		File pushDir = getPushDir();
		if (pushDir != null)
		{
			list.addAll(Arrays.asList(pushDir.listFiles()));
		}
		return list;
	}

	/**
	 * 获取上传的文件
	 * 
	 * @param list
	 *            new一个
	 */
	public static void getPushFiles(List<File> list)
	{
		getAllFiles(list, getPushDir(), ConstantsUtils.FILE_TYPE);
	}

	/**
	 * 获取root目录下的所有后缀名为name的字段
	 *
	 * @param root
	 *            文件根目录
	 * @param name
	 *            文件后缀名 .zip等，加上.
	 * @return
	 */
	public static void getAllFiles(List<File> list, File root, String name)
	{
		File files[] = root.listFiles();
		if (files != null)
		{
			for (File f : files)
			{
				if (f.isDirectory())
				{
					getAllFiles(list, f, name);
				}
				else
				{
					if (f.getName().endsWith(name))
					{
						list.add(f);
					}
				}
			}
		}
	}

	public static boolean deleteFile(File file)
	{
		if (file == null || !file.exists())
		{
			return true;
		}
		else
		{
			if (file.isFile())
			{
				return file.delete();
			}
			else if (file.isDirectory())
			{
				return deleteContents(file);
			}

		}
		return false;
	}

	/**
	 * 删除 dir目录下的所有文件
	 *
	 * @param dir
	 * @return 是否删除成功
	 */
	public static boolean deleteContents(File dir)
	{
		if (dir == null || !dir.exists() || dir.isFile())
		{
			return true;
		}

		File[] files = dir.listFiles();
		boolean success = true;
		if (files != null)
		{
			for (File file : files)
			{
				if (file.isDirectory())
				{
					success &= deleteContents(file);
				}
				if (!file.delete())
				{
					Log.e("FileUtils", "Failed to delete " + file);
					success = false;
				}
			}
		}
		return success;
	}

	/**
	 * 压缩成zip后立刻调用split进行文件分割, 分割后的文件放到原文件目录下
	 * 
	 * @param file
	 *            压缩后的文件
	 */
	public static void split(File file)
	{
		if (file == null || !file.exists() || !file.isFile())
			return;

		splitFile(file, FileUtils.getPushDir().getAbsolutePath(), 512);
	}

	/**
	 * 切分文件
	 *
	 * @param file
	 *            被切分的文件
	 * @param path
	 *            切分后的文件的所在路径 /切片 原文件名_6_1
	 * @param size
	 *            分片的大小 如果file.length()<size,不做处理
	 */
	public static void splitFile(File file, String path, long size)
	{
		if (file != null)
		{
			if (size < 0)
				size = 512; // UploadResponseHandler.BUFFER_SIZE
			int mTotalCnt = (int) (file.length() / size) + 1;
			Log.d(Constants.TAG, "file count " + mTotalCnt);
			long mPosOffset = 0;
			long length = 0;
			RandomAccessFile randomAccessFile = null;
			FileOutputStream outputStream = null;
			// 这个必须比size小
			byte[] buffer = new byte[512];
			// byte[] buffer = new byte[UploadResponseHandler.BUFFER_SIZE];
			for (int i = 0; i < mTotalCnt; i++)
			{
				try
				{
					// 指向的文件 原文件名_6_1;
					outputStream = new FileOutputStream(path + File.separator
					        + file.getName() + "_" + mTotalCnt + "_" + i);
				} catch (FileNotFoundException e)
				{
					e.printStackTrace();
				}

				try
				{
					randomAccessFile = new RandomAccessFile(file, "r");
					randomAccessFile.seek(mPosOffset);
				} catch (FileNotFoundException e)
				{
					if (randomAccessFile != null)
					{
						try
						{
							randomAccessFile.close();
						} catch (IOException e1)
						{
						}
					}
					return;
				} catch (IOException e)
				{
					if (randomAccessFile != null)
					{
						try
						{
							randomAccessFile.close();
						} catch (IOException e1)
						{
						}
					}
					return;
				}

				try
				{
					// 从文件中读内容
					length = randomAccessFile.read(buffer);
				} catch (IOException e)
				{
					if (randomAccessFile != null)
					{
						try
						{
							randomAccessFile.close();
						} catch (IOException e1)
						{
						}
					}
					return;
				}

				try
				{
					outputStream.write(buffer, 0, (int) length);
				} catch (IOException e)
				{

					if (randomAccessFile != null)
					{
						try
						{
							randomAccessFile.close();
						} catch (IOException e1)
						{
						}
					}
					return;
				}
				mPosOffset += length;

			}
			// TODO 删除原来的zip文件
			file.delete();
		}

	}
}
